home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Core / ValueNS.cpp < prev   
Encoding:
C/C++ Source or Header  |  1997-02-13  |  15.9 KB  |  608 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ValueNS.cpp
  3.  
  4.     Contains:    Implementation of ODValueNameSpace class
  5.  
  6.     Owned by:    Ed Lai
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <5>     9/23/96    EL        1242543: Throw in register for wrong type.
  13.          <4>      6/5/96    TJ        1330687: Now correctly pass buffer ptr by
  14.                                     value in WriteSizeAndBytes
  15.          <3>     5/24/96    jpa        1330687: Fixed parameter ordering for
  16.                                     PlatformFile::Write calls.
  17.          <2>     5/23/96    RA        1330687: ValueNS should use
  18.                                     platformFile->write instead of FSWrite
  19.  
  20.     To Do:
  21.         Get prefs file name from a string resource.
  22.     In Progress:
  23.         
  24. */
  25.  
  26. #ifndef _PLFMDEF_
  27. #include "PlfmDef.h"
  28. #endif
  29.  
  30. #ifndef _EXCEPT_
  31. #include "Except.h"
  32. #endif
  33.  
  34. #define ODValueNameSpace_Class_Source
  35. #include <ValueNS.xih>
  36.  
  37. #ifndef SOM_ODNameSpace_xh
  38. #include "NamSpac.xh"
  39. #endif
  40.  
  41. #ifndef _STRHSHTB_
  42. #include "StrHshTb.h"
  43. #endif
  44.  
  45. #ifndef _PASCLSTR_
  46. #include "PasclStr.h"
  47. #endif
  48.  
  49. #ifndef __STRING__
  50. #include <string.h>
  51. #endif
  52.  
  53. #ifndef __LIMITS__
  54. #include <limits.h>
  55. #endif
  56.  
  57. #ifndef __LOWMEM__
  58. #include <LowMem.h>
  59. #endif
  60.  
  61. #ifndef _ODTYPES_
  62. #include <ODTypes.h>
  63. #endif
  64.  
  65. #ifndef SOM_ODStorageUnitView_xh
  66. #include <SUView.xh>
  67. #endif
  68.  
  69. #ifndef _ODMEMORY_
  70. #include "ODMemory.h"
  71. #endif
  72.  
  73. #ifndef _ISOSTR_
  74. #include "ISOStr.h"
  75. #endif
  76.  
  77. #ifndef SOM_ODValueIterator_xh
  78. #include <ValueItr.xh>
  79. #endif
  80.  
  81. #ifndef _BNDNSUTL_
  82. #include "BndNSUtl.h"
  83. #endif
  84.  
  85. #ifndef _PLFMFILE_
  86. #include "PLFMFile.h"
  87. #endif
  88.  
  89. #ifndef _STORUTIL_
  90. #include <StorUtil.h>
  91. #endif
  92.  
  93. #ifndef _BARRAY_
  94. #include <BArray.h>
  95. #endif
  96.  
  97. #ifndef _TEMPOBJ_
  98. #include <TempObj.h>
  99. #endif
  100.  
  101. #ifndef _UTILERRS_
  102. #include <UtilErrs.h>
  103. #endif
  104.  
  105. #ifndef SOM_ODNameSpaceManager_xh
  106. #include "NmSpcMg.xh"
  107. #endif
  108.  
  109. #pragma segment ODValueNameSpace
  110.  
  111. //==============================================================================
  112. // Implementation notes
  113. //==============================================================================
  114.  
  115. /*
  116. Hash tables used for the implementation are lazily instantiated. They will be
  117. created at the first request to add an entry.
  118. */
  119.  
  120. //==============================================================================
  121. // Constants
  122. //==============================================================================
  123.  
  124. //==============================================================================
  125. // Function Prototype
  126. //==============================================================================
  127.  
  128. //==============================================================================
  129. // Local Functions
  130. //==============================================================================
  131.  
  132. //==============================================================================
  133. // ODValueNameSpace
  134. //==============================================================================
  135.  
  136. //------------------------------------------------------------------------------
  137. // ODValueNameSpace: InitValueNameSpace
  138. //------------------------------------------------------------------------------
  139.  
  140. SOM_Scope void  SOMLINK ODValueNameSpaceInitValueNameSpace(ODValueNameSpace *somSelf, Environment *ev,
  141.         ODNameSpaceManager*        mgr,
  142.         ODNameSpace*            parent,
  143.         ODULong                    numExpectedEntries,
  144.         ODISOStr                name)
  145. {
  146.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  147.     ODValueNameSpaceMethodDebug("ODValueNameSpace","InitValueNameSpace");
  148.  
  149.     SOM_TRY
  150.  
  151.     somSelf->SetType( ev, kODNSDataTypeODValue );
  152.     somSelf->InitNameSpace(ev, mgr, parent, numExpectedEntries, name);
  153.     
  154.     SOM_CATCH_ALL
  155.     SOM_ENDTRY
  156. }
  157.  
  158. //------------------------------------------------------------------------------
  159. // ODValueNameSpace: ~ODValueNameSpace
  160. //------------------------------------------------------------------------------
  161.  
  162. SOM_Scope void  SOMLINK ODValueNameSpacesomUninit(ODValueNameSpace *somSelf)
  163. {
  164.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  165.     ODValueNameSpaceMethodDebug("ODValueNameSpace","somUninit");
  166.  
  167.     Environment* ev = somGetGlobalEnvironment();
  168.     
  169.     SOM_TRY
  170.  
  171.     StringHashTable* hashTable = somSelf->GetHashTable(ev);
  172.     StringHashTableIterator* hashTableItr = new StringHashTableIterator(hashTable);
  173.  
  174.     if (hashTableItr)
  175.     {
  176.         ODULong    len;
  177.         ODUByte*    string;
  178.         ODPtr buffer = kODNULL;
  179.         ODULong size = 0;
  180.         for(hashTableItr->First(&string, &len ,&buffer, &size);
  181.             hashTableItr->IsNotComplete();
  182.             hashTableItr->Next(&string, &len ,&buffer, &size))
  183.         {
  184.             ODDisposePtr( buffer );
  185.         }
  186.         
  187.         delete ( hashTableItr );
  188.     }
  189.     
  190.     ODValueNameSpace_parent_ODNameSpace_somUninit(somSelf);
  191.  
  192.     SOM_CATCH_ALL
  193.     SOM_ENDTRY
  194. }
  195.  
  196. //------------------------------------------------------------------------------
  197. // ODValueNameSpace: Purge
  198. //------------------------------------------------------------------------------
  199.  
  200. SOM_Scope ODSize  SOMLINK ODValueNameSpacePurge(ODValueNameSpace *somSelf, Environment *ev,
  201.         ODSize size)
  202. {
  203.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  204.     ODValueNameSpaceMethodDebug("ODValueNameSpace","Purge");
  205.  
  206.     ODUnused(size);
  207.     return 0;
  208. }
  209.  
  210. //------------------------------------------------------------------------------
  211. // ODValueNameSpace: Register
  212. //------------------------------------------------------------------------------
  213.  
  214. SOM_Scope void  SOMLINK ODValueNameSpaceRegister(ODValueNameSpace *somSelf, Environment *ev,
  215.         ODISOStr key, ODByteArray* value)
  216. {
  217.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  218.     ODValueNameSpaceMethodDebug("ODValueNameSpace","Register");
  219.  
  220.     ODPtr buffer = kODNULL;
  221.     ODULong size = 0;
  222.     
  223.     if (somSelf->GetType(ev) != kODNSDataTypeODValue)
  224.         THROW(kODErrInvalidNSType);
  225.  
  226.     SOM_TRY
  227.     
  228.     ODULong len = ODISOStrLength(key);
  229.     StringHashTable* hashTable = somSelf->GetHashTable(ev);
  230.     
  231.     if (hashTable->Find((ODUByte*)key, len, &buffer, &size))
  232.     {
  233.         // destroy pre-existing old value to prevent a memory leak
  234.         ODDisposePtr( buffer );
  235.         hashTable->Remove((ODUByte*)key, len);
  236.     }
  237.     
  238.     ODULong valueLength = value->_length;
  239.     buffer = ODNewPtrClear(valueLength, kDefaultHeapID);
  240.     ODBlockMove( value->_buffer, buffer, valueLength );
  241.     hashTable->Insert((ODUByte*)key,len, buffer, valueLength);
  242.  
  243.     if (somSelf->GetNameSpaceManager(ev)->
  244.                        GetMaxISOStrLength(ev) < valueLength)
  245.         somSelf->GetNameSpaceManager(ev)->
  246.                         SetMaxISOStrLength(ev, valueLength);
  247.     
  248.     SOM_CATCH_ALL
  249.     SOM_ENDTRY
  250. }
  251.  
  252. //------------------------------------------------------------------------------
  253. // ODValueNameSpace: Unregister
  254. //------------------------------------------------------------------------------
  255.  
  256. SOM_Scope void  SOMLINK ODValueNameSpaceUnregister(ODValueNameSpace *somSelf, Environment *ev,
  257.         ODISOStr key)
  258. {
  259.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  260.     ODValueNameSpaceMethodDebug("ODValueNameSpace","ODValueNameSpaceUnregister");
  261.  
  262.     ODPtr buffer = kODNULL;
  263.     ODULong size = 0;
  264.  
  265.     SOM_TRY
  266.  
  267.     size_t len = strlen(key);
  268.     ODBoolean result = somSelf->GetHashTable(ev)->Find((ODUByte*)key, len, &buffer, &size);
  269.     ODDisposePtr( buffer );
  270.     if (result)
  271.         somSelf->GetHashTable(ev)->Remove((ODUByte*)key, len);
  272.     
  273.     SOM_CATCH_ALL
  274.     SOM_ENDTRY
  275. }
  276.  
  277. //------------------------------------------------------------------------------
  278. // ODValueNameSpace: GetEntry
  279. //------------------------------------------------------------------------------
  280.  
  281. SOM_Scope ODBoolean  SOMLINK ODValueNameSpaceGetEntry(ODValueNameSpace *somSelf, Environment *ev,
  282.         ODISOStr key, ODByteArray* value)
  283. {
  284.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  285.     ODValueNameSpaceMethodDebug("ODValueNameSpace","GetEntry");
  286.  
  287.     ODBoolean    result = kODFalse;
  288.     value->_buffer = kODNULL;
  289.     value->_maximum = value->_length = 0;
  290.  
  291.     SOM_TRY
  292.  
  293.     ODPtr buffer = kODNULL;
  294.     ODULong size = 0;
  295.  
  296.     if (somSelf->GetType(ev) == kODNSDataTypeODValue)
  297.     {
  298.         size_t len = strlen(key);
  299.         result = somSelf->GetHashTable(ev)->Find((ODUByte*)key, len, 
  300.                                                                 &buffer, &size);
  301.         if ( result == kODFalse )
  302.         {
  303.             ODValueNameSpace *parent =(ODValueNameSpace*)somSelf->GetParent(ev);
  304.             if (parent)
  305.             {
  306.                 if (parent->GetType(ev) == kODNSDataTypeODValue)
  307.                     result = parent->GetEntry(ev, key, value);
  308.             }
  309.         }
  310.         else
  311.         {
  312.             value->_length = value->_maximum = size;
  313.             if ( size > 0 )
  314.             {
  315.                 value->_buffer = (octet*) ODNewPtr(size, kDefaultHeapID);
  316.                 ODBlockMove( buffer, value->_buffer, size);
  317.             }
  318.         }
  319.     }
  320.     
  321.     SOM_CATCH_ALL
  322.         result = kODFalse;
  323.     SOM_ENDTRY
  324.  
  325.     return result;
  326. }
  327.  
  328. //------------------------------------------------------------------------------
  329. // ODValueNameSpace: CreateIterator
  330. //------------------------------------------------------------------------------
  331.  
  332. SOM_Scope ODValueIterator*  SOMLINK ODValueNameSpaceCreateIterator(ODValueNameSpace *somSelf, Environment *ev)
  333. {
  334.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  335.     ODValueNameSpaceMethodDebug("ODValueNameSpace","CreateIterator");
  336.  
  337.     ODValueIterator* theValueIterator = kODNULL;
  338.     
  339.     SOM_TRY
  340.     
  341.     theValueIterator = new ODValueIterator;
  342.     THROW_IF_NULL(theValueIterator); // check all SOM new's for nil
  343.     theValueIterator->InitValueIterator(ev, somSelf);
  344.     
  345.     SOM_CATCH_ALL
  346.     SOM_ENDTRY
  347.  
  348.     return theValueIterator;
  349. }
  350.  
  351. //------------------------------------------------------------------------------
  352. // WriteULong
  353. //------------------------------------------------------------------------------
  354.  
  355. static void WriteULong(PlatformFile* file, ODStorageUnitView* view,
  356.                             ODULong value)
  357. {
  358.     ODSLong    length ;
  359.     Environment* ev = somGetGlobalEnvironment ();
  360.  
  361.     length = sizeof(value);
  362.     if (view) {
  363.         StorageUnitViewSetValue(view, ev, length, &value);
  364.     }
  365.     else
  366.     {
  367.         ODSLong savedLength = length;
  368.         file->Write(&value,&length);
  369.         if (savedLength != length)
  370.             THROW(kODErrWriteErr);
  371.     }
  372. }
  373.  
  374. //------------------------------------------------------------------------------
  375. // WriteSizeAndBytes
  376. //------------------------------------------------------------------------------
  377.  
  378. static void WriteSizeAndBytes(PlatformFile* file, ODStorageUnitView* view,
  379.                                 ODPtr bytes, ODULong length)
  380. {
  381.     Environment* ev = somGetGlobalEnvironment ();
  382.  
  383.     // WRITE LENGTH OF STREAM
  384.     WriteULong(file, view, length);
  385.  
  386.     // WRITE STREAM
  387.     if (view)
  388.         StorageUnitViewSetValue(view, ev, length, bytes);
  389.     else
  390.     {
  391.         ODSLong writtenLength = length;
  392.         file->Write(bytes,&writtenLength);
  393.         if (writtenLength != length)
  394.             THROW(kODErrWriteErr);
  395.     }
  396. }
  397.  
  398. //------------------------------------------------------------------------------
  399. // ODValueNameSpace: Write
  400. //------------------------------------------------------------------------------
  401.  
  402. SOM_Scope void  SOMLINK ODValueNameSpaceWrite(ODValueNameSpace *somSelf, Environment *ev,
  403.         PlatformFile* file, ODStorageUnitView* view)
  404. {
  405.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  406.     ODValueNameSpaceMethodDebug("ODValueNameSpace","Write");
  407.  
  408.     SOM_TRY
  409.     
  410.     // WRITE NAME
  411.     { TempODISOStr selfName(somSelf->GetName(ev));
  412.       WriteSizeAndBytes(file, view, 
  413.           (ODISOStr) selfName, ODISOStrLength( (ODISOStr) selfName ));
  414.     }
  415.     
  416.     // WRITE NUMENTRIES
  417.     ODULong numEntries = somSelf->GetNumEntries(ev);
  418.     WriteULong(file, view, numEntries);
  419.  
  420.     if (numEntries)
  421.     {
  422.         StringHashTableIterator    iter(somSelf->GetHashTable(ev));
  423.         ODUByte*                    key;
  424.         ODULong                    keyLength;
  425.         ODPtr                        value;
  426.         ODULong                    valueLength;
  427.         
  428.         for (iter.First(&key, &keyLength, &value, &valueLength)
  429.                 ;iter.IsNotComplete()
  430.                 ;iter.Next(&key, &keyLength, &value, &valueLength))
  431.         {
  432.             WriteSizeAndBytes(file, view, key, keyLength);
  433.             WriteSizeAndBytes(file, view, value, valueLength);
  434.         }
  435.     }
  436.     
  437.     SOM_CATCH_ALL
  438.     SOM_ENDTRY
  439. }
  440.  
  441. //------------------------------------------------------------------------------
  442. // ODValueNameSpace: WriteToFile
  443. //------------------------------------------------------------------------------
  444.  
  445. SOM_Scope void  SOMLINK ODValueNameSpaceWriteToFile(ODValueNameSpace *somSelf, Environment *ev,
  446.         ODByteArray* file)
  447. {
  448.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  449.     ODValueNameSpaceMethodDebug("ODValueNameSpace","WriteToFile");
  450.  
  451.     SOM_TRY
  452.  
  453.     PlatformFile*    platFile = ((PlatformFile*) file->_buffer);
  454.     somSelf->Write(ev, platFile, (ODStorageUnitView*)kODNULL);
  455.     
  456.     SOM_CATCH_ALL
  457.     SOM_ENDTRY
  458. }
  459.  
  460. //------------------------------------------------------------------------------
  461. // ODValueNameSpace: WriteToStorage
  462. //------------------------------------------------------------------------------
  463.  
  464. SOM_Scope void  SOMLINK ODValueNameSpaceWriteToStorage(ODValueNameSpace *somSelf, Environment *ev,
  465.         ODStorageUnitView* view)
  466. {
  467.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  468.     ODValueNameSpaceMethodDebug("ODValueNameSpace","WriteToStorage");
  469.  
  470.     SOM_TRY
  471.  
  472.     somSelf->Write(ev,0, view);
  473.     
  474.     SOM_CATCH_ALL
  475.     SOM_ENDTRY
  476. }
  477.  
  478. //------------------------------------------------------------------------------
  479. // ODValueNameSpace: Read
  480. //------------------------------------------------------------------------------
  481.  
  482. SOM_Scope void  SOMLINK ODValueNameSpaceRead(ODValueNameSpace *somSelf, Environment *ev,
  483.         PlatformFile* file, ODStorageUnitView* view)
  484. {
  485.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  486.     ODValueNameSpaceMethodDebug("ODValueNameSpace","Read");
  487.  
  488.     SOM_TRY
  489.  
  490.     {   // READ NAME-VERIFY THAT IT'S THE SAME
  491.         ODULong nameLength = ReadSize(file  , view);
  492.         TempODISOStr name = (ODISOStr)ODNewPtr(nameLength + 1, kDefaultHeapID);
  493.     
  494.         ReadBytes(file , view, name, &nameLength);
  495.         ((ODISOStr) name)[nameLength] = 0;
  496.     
  497.         TempODISOStr selfName(somSelf->GetName(ev)); // make sure it's deleted
  498.         
  499.         if ( ! ODISOStrEqual(name, selfName))
  500.             THROW(kODErrInvalidNSName);
  501.     }
  502.  
  503.     // READ NUM ENTRIES
  504.     ODULong numEntries = ReadSize(file , view);
  505.  
  506.     // MORE THAN ONE ENTRY?
  507.     if (numEntries)
  508.     {
  509.         ODISOStr    key = kODNULL;
  510.         ODPtr        value = kODNULL;
  511.         ODULong    keyLength;
  512.         ODULong    valueLength;
  513.         ODULong    bufferSize = UCHAR_MAX;
  514.         ODPtr        buffer = ODNewPtr(bufferSize, kDefaultHeapID); // FOR FASTER KEY READING
  515.         ODBoolean    allocatedKey = kODFalse;
  516.         ODVolatile(allocatedKey);
  517.         
  518.         ODNameSpaceManager* tempNSMgr = somSelf->GetNameSpaceManager(ev); //cache reference to speed loop
  519.         StringHashTable* tempHashTable = somSelf->GetHashTable(ev);
  520.         
  521.         TRY
  522.             for (ODULong i = 0; i < numEntries; i++)
  523.             {
  524.                 keyLength = ReadSize(file , view);
  525.                 if (keyLength > bufferSize)
  526.                 {
  527.                     key = (ODISOStr)ODNewPtr(keyLength, kDefaultHeapID);
  528.                     allocatedKey = kODTrue;
  529.                 }
  530.                 else
  531.                     key = (ODISOStr)buffer;
  532.  
  533.                 ReadBytes(file , view, key, &keyLength);
  534.  
  535.                 TRY
  536.                     valueLength = ReadSize(file , view);
  537.                     value = ODNewPtr(valueLength, kDefaultHeapID);
  538.                     TRY
  539.                         ReadBytes(file , view, value, 
  540.                                                                    &valueLength);
  541.                         tempHashTable->Insert((unsigned char*)key,
  542.                                                   keyLength, value, valueLength);
  543.  
  544.                         if (tempNSMgr->GetMaxISOStrLength(ev) < valueLength)
  545.                             tempNSMgr->SetMaxISOStrLength(ev, valueLength);
  546.                     
  547.                     CATCH_ALL
  548.                         ODDisposePtr(value);
  549.                         RERAISE;
  550.                     ENDTRY
  551.                 CATCH_ALL
  552.                     if (allocatedKey)
  553.                         ODDisposePtr(key);
  554.                     RERAISE;
  555.                 ENDTRY
  556.  
  557.                 if (allocatedKey)
  558.                     ODDisposePtr(key);
  559.             }
  560.             
  561.             ODDisposePtr(buffer);
  562.         CATCH_ALL
  563.             ODDisposePtr(buffer);
  564.             RERAISE;
  565.         ENDTRY
  566.     }
  567.     
  568.     SOM_CATCH_ALL
  569.     SOM_ENDTRY
  570. }
  571.  
  572. //------------------------------------------------------------------------------
  573. // ODValueNameSpace: ReadFromFile
  574. //------------------------------------------------------------------------------
  575.  
  576. SOM_Scope void  SOMLINK ODValueNameSpaceReadFromFile(ODValueNameSpace *somSelf, Environment *ev,
  577.         ODByteArray* file)
  578. {
  579.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  580.     ODValueNameSpaceMethodDebug("ODValueNameSpace","ReadFromFile");
  581.     
  582.     SOM_TRY
  583.     
  584.     PlatformFile*    platFile = ((PlatformFile*) file->_buffer);
  585.     somSelf->Read(ev, platFile, (ODStorageUnitView*)kODNULL);
  586.     
  587.     SOM_CATCH_ALL
  588.     SOM_ENDTRY
  589. }
  590.  
  591. //------------------------------------------------------------------------------
  592. // ODValueNameSpace: ReadFromStorage
  593. //------------------------------------------------------------------------------
  594.  
  595. SOM_Scope void  SOMLINK ODValueNameSpaceReadFromStorage(ODValueNameSpace *somSelf, Environment *ev,
  596.         ODStorageUnitView* view)
  597. {
  598.     /* ODValueNameSpaceData *somThis = ODValueNameSpaceGetData(somSelf); */
  599.     ODValueNameSpaceMethodDebug("ODValueNameSpace","ReadFromStorage");
  600.  
  601.     SOM_TRY
  602.  
  603.     somSelf->Read(ev,0, view);
  604.     
  605.     SOM_CATCH_ALL
  606.     SOM_ENDTRY
  607. }
  608.